iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0

本系列文章經過重新編排和擴充,已出書為ECMAScript關鍵30天。原始文章因當時準備時程緊迫,多少有些許錯誤。為了避免造成讀者的困擾,以及配合書籍的內容規劃,將會陸續更新本系列文章。
本篇文章在 2021/11/2 已更新。

ES2015 中,將 Promise 標準化,解決了以往要寫非同步時容易產生的 callback hell。不過寫久了就會發現,如果有多個非同步,或是有複雜的判斷邏輯時,Promise 的寫法還是會讓程式產生巢狀,語意上也不好解讀。

因此在 ES2017 中,最重要的特性就是新增非同步寫法的方式 - 以 Promise 結合 Generator 的特性,以awaitasync作為非同步函式的前綴字,來簡化 Promise 的實現。

基本用法是當要宣告非同步函式時,使用async作為函式的前綴字。當要執行函式時,使用await作為呼叫函式的前綴字。另外在函式裡有執行到非同步的地方,也可以用await表示這裡需要等待結果回傳。

async function allResult() {
  const r1 = await fn1();
  const r2 = await fn2();
  return [r1, r2];
}
const result = await allResult();

跟原本的 Promise 寫法比較看看。先建立一些非同步函式 -

const downloadData() = () => {
    return new Promise((resolve, reject) => {...})
}
const processData() = () => {
    return new Promise((resolve, reject) => {...})
}
const ProcessError() = () => {
    return new Promise((resolve, reject) => {...})
}

getData 函式回傳的 Promise 會導致 promise chaining,將函式分隔成多個部份。

function getData(params) {
  return downloadData(params) // returns a promise
    .then(v => {
      return processData(params); // returns a promise
    });
    .catch(e => {
      return ProcessError(params); // returns a promise
    })
}

以async & await 改寫 getData 函式的話,就不會產生 promise chaining,並且可以搭配 try catch 處理意外錯誤。

async function getData(params) {
  let v;
  try {
    v = await downloadData(params);
  } catch(e) {
    v = await ProcessError(params);
  }
  return processData(vparams);
}

參考資源


上一篇
ES2016(ES7) - Array、運算子
下一篇
ES2017(ES8) - string、Object
系列文
從ES到ESNext - 30天輕鬆掌握ECMAScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言